// 引入用户模型
const User = require('../models/users')
const Question = require('../models/question')
const Answer = require('../models/answers')
// jwt
const jsonwebtoken = require('jsonwebtoken')
// 密钥
const { SECRET } = require('../config')

class UserController {
  // =========================查询所有的用户==================
  async findAllUser(ctx) {
        // 分页逻辑
        let { perPage = 10, page = 1}  = ctx.query // 默认每页十条数据，从第一页起步
        // 防止输入负数
        perPage = Math.max(perPage * 1, 1) 
        page = Math.max(page * 1,1) 
    // 模糊搜索,使用正则表达式
    const userList = await User.find({
      name: new RegExp(ctx.query.q)
    }).limit(perPage).skip((page-1) * perPage)

    ctx.body = {
      message: '请求成功',
      data: userList
    }
  }

  // ==========================查找特定用户====================
  async findById(ctx) {
     // 从请求url中获取需要额外返回的字段,默认为空
     const fields = ctx.query.fields || ''
     // 处理字符串,字段是以分号间隔的，去掉空字符串，字段格式为 ‘+a +b’ 
     const selectFields = fields.split(';').filter(item=>item).map(item=>' +'+item).join('')
    // 默认是只返回id，name，，headline和avatar字段的
    const user = await User.findById(ctx.params.id).select(selectFields).populate('following')
    if(!user) {
      ctx.throw(404,'用户不存在')
    }
    ctx.body = user
  }

  // =========================新建用户=======================
  async addUser(ctx) {
    ctx.verifyParams({
      name: {type: 'string',required: true},
      password: {type: 'string',required: true}
    })
    // 校验用户是否已存在
    const {name} = ctx.request.body
    const isRepeatedUser = await User.findOne({name})
    if (isRepeatedUser) {
      ctx.throw(409,'用户已存在')
    }
    // 用户校验通过
    // 新增数据保存，body里就是用户信息数据
   const user = await new User(ctx.request.body).save()
   ctx.body = user
  }

  // =======================更新用户======================
  async updateUser(ctx) {
    // 参数校验
    ctx.verifyParams({
      name: {type: 'string',required: false},
      password: {type: 'string',required: false},
      avatar:{type: 'string', required: false},
      gender:{type: 'string', required: false},
      headline:{type: 'string', required: false},
      locations:{type: 'array',item: 'string', required: false},  // itemType--数组每一项的类型
      business:{type: 'string', required: false},
      employments:{type: 'array', itemType: 'object', required: false},
      educations:{type: 'array',itemType: 'object', required: false},  
    })  
    const user = await User.findByIdAndUpdate(ctx.params.id, ctx.request.body)
    if(!user) {
      ctx.throw(404)
    }
    ctx.body = user
  }
  // ======================= 删除用户 ==========================
  async deleteUser(ctx) {
    const user = await User.findByIdAndRemove(ctx.params.id)
    if(!user) {
      ctx.throw(404)
    }
    ctx.status = 204
  }
  // ======================== 登陆=============================
  async login(ctx) {
    ctx.verifyParams({
      name: {type: 'string',required: true},
      password: {type: 'string',required: true}
    })
    const user = await User.findOne(ctx.request.body) 
    if (!user) {
      ctx.throw(401,'用户或密码不正确')
    }
    // 用户非敏感信息，生成token
    const { _id,name } = user
    const token = jsonwebtoken.sign({userId:_id, userName:name}, SECRET, {expiresIn:'12h'})
    const temp = jsonwebtoken.verify(token, SECRET)
    console.log(temp)
    ctx.body = { 
      message: '登陆成功',
      data: {
        token
      }
    }
  }

  // =======================获取关注列表=======================
  async listFollowing(ctx) {
    // 获取关注的用户，populate是填充，用户_id再去获取用户的信息,following字段会被完整的用户信息替换
    const user = await User.findById(ctx.params.id).select('+following').populate('following')
    if (!user) {
      ctx.throw(404, '用户不存在！')
    }
    ctx.body = user.following
  }
  // ========================用户是否存在=======================
  async checkUserExist (ctx, next) {
  const user = await User.findById(ctx.params.id)
  if(!user) {
    ctx.throw(404, '用户不存在！')
  }
  await next()
}

  // =======================关注用户============================
  // 被关注用户的id，保存到当前用户的关注者列表，当前用户的id可以从jwt中获取
  async followingUser(ctx) {
    const curUser = await User.findById(ctx.state.user.userId).select('+following')
    // 判断用户是否已关注，但注意following中的数据并不是字符串，因此需要进行转换
    // 不能关注自己
    if (!curUser.following.map(id=>id.toString()).includes(ctx.params.id) && ctx.params.id!==ctx.state.user.userId) {
      curUser.following.push(ctx.params.id)
      // 保存到数据库
      curUser.save()
    } 
    // 操作成功 
    ctx.status = 204 
  }

  // =======================取消关注===========================
  async unfollowing (ctx) {
    const curUser = await User.findById(ctx.state.user.userId).select('+following')
    // 获取在关注列表中的索引位置
    const index = curUser.following.map(id=>id.toString()).indexOf(ctx.params.id)
    if (index > -1) {
      curUser.following.splice(index,1)
      curUser.save()
    }
    ctx.status = 204
  }

  // =======================获取所有的粉丝列表==================
  async listFollowers (ctx) {
    // 查询用户列表，看用户是否关注列表中是否有当前用户
    const user = await User.find({following: ctx.params.id})
    ctx.body = user 
  }

  // ======================用户提问的问题列表==================
  async listQuestion(ctx) {
    const questionList = await Question.find({questioner: ctx.params.id})
    ctx.body = questionList
  }

  // =======================赞同的答案列表======================
  async listApprovedAnswer(ctx) {
    const user = await User.findById(ctx.params.id).select('+approvedAnswer').populate('approvedAnswer')
    if (!user) {
      ctx.throw(404, '用户不存在')
    }
    ctx.body = user.approvedAnswer
  }

  // ========================赞同答案========================
  async approvedAnswer(ctx, next) {
    // 获取当前的登陆用户信息
    const user = await User.findById(ctx.state.user.userId).select('+approvedAnswer')
    const isApproved = user.approvedAnswer.map(id=>id.toString()).includes(ctx.params.answerId) // 是否已赞同回答
    if (!isApproved) {
      // 添加进赞同数组并保存
      user.approvedAnswer.push(ctx.params.answerId)
      user.save()
      // 修改回答的赞同数 ,+1
     const answer = await Answer.findByIdAndUpdate(ctx.params.answerId, {$inc: {approvedCount: 1}}, {new: true})
    }
    await next()
    ctx.status = 204
  }

  // ======================取消赞同答案====================
  async unapprovedAnswer(ctx) {
      // 获取当前的登陆用户信息
      const user = await User.findById(ctx.state.user.userId).select('+approvedAnswer')
      const index = user.approvedAnswer.map(id=>id.toString()).indexOf(ctx.params.answerId) // 是否已赞同
      if (index > -1) {
        // 移除赞同数组并保存
        user.approvedAnswer.splice(index, 1)
        user.save()
        // 修改回答的赞同数 ,-1
        await Answer.findByIdAndUpdate(ctx.params.answerId, {$inc: {approvedCount: -1}})
      }
      ctx.status = 204    
  }
  // ======================反对回答=======================
  async opposeAnswer(ctx,next) {
    // 获取当前的登陆用户信息
    const user = await User.findById(ctx.state.user.userId).select('+opposeAnswer')
    const isOppose = user.opposeAnswer.map(id=>id.toString()).includes(ctx.params.answerId) // 是否已反对回答
    if (!isOppose) {
      // 添加进反对数组并保存
      user.opposeAnswer.push(ctx.params.answerId)
      user.save()
    }
    await next()
    ctx.status = 204
  }
  // ========================取消反对回答======================
  async unOpposeAnswer(ctx) {
     // 获取当前的登陆用户信息
     const user = await User.findById(ctx.state.user.userId).select('+opposeAnswer')
     const index = user.opposeAnswer.map(id=>id.toString()).indexOf(ctx.params.answerId) // 是否已赞同
     if (index > -1) {
       // 移除赞同数组并保存
       user.opposeAnswer.splice(index, 1)
       user.save()
     }
     ctx.status = 204    
  }
  // =======================收藏回答列表======================
  async getCollectionsList(ctx) {
    // 这里不能使用ctx.state.user 来获取用户信息，因为这一步不校验权限，ctx.state里是没有user信息的
    const user = await User.findById(ctx.params.id).select('+collections').populate('collections')
    // 返回收藏列表
    ctx.body = user.collections
  }
  // =======================收藏回答========================
  async addCollections(ctx) { 
    // 获取用户信息
    const user = await User.findById(ctx.state.user.userId).select('+collections')
    const isCollect = user.collections.map(id=>id.toString()).includes(ctx.params.answerId)
    if (!isCollect) {
      user.collections.push(ctx.params.answerId)
      user.save()
    }
    ctx.status = 204
  }

  // =======================取消收藏========================
  async removeCollections(ctx) {
    // 获取用户信息
    const user = await User.findById(ctx.state.user.userId).select('+collections')
    const index = user.collections.map(id=>id.toString()).indexOf(ctx.params.answerId)
    if (index > -1) {
      user.collections.splice(index, 1)
      user.save()
    }
    ctx.status = 204
  }
}

module.exports = new UserController()